package com.jbm.core.iface;

import com.google.protobuf.ByteString;
import com.jbm.core.common.ConnectAgent;
import com.jbm.core.common.IoSessionShell;
import com.jbm.core.common.OHByte;
import com.jbm.core.pb.PBIAcross;
import com.jbm.core.pb.PBIFileObject;
import com.jbm.onehome.common.OHInterface;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.session.IoSession;

import java.io.File;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;

/**
 * Created by root on 17-5-24.
 */
public class IFileObject extends IAcross
{
	public IFileObject(IAcross ia)
	{
		super(ia);
	}

	public IFileObject ()
	{
		super();
		recvsize = 0l;
	}

	public IFileObject(String filepath,String filename)
	{
		this.filepath = filepath;
		this.filename = filename;
	}

	public String filepath;
	public String filename;
	public String filetype;
//	public String storepath;
	public String storename;
	public long filesize;

	private long recvsize;
	private RandomAccessFile raf;
//	private String raf_name;

	public Object StartDecode(Object in, IoSessionShell ios) throws Exception
	{
		PBIFileObject.IFileObject.Builder fob = null;
		if ( in instanceof ByteString )
			fob = PBIFileObject.IFileObject.parseFrom((ByteString)in).toBuilder();
		else
			fob = ((PBIFileObject.IFileObject)in).toBuilder();

		recvsize = 0l;

		String sp = null;
		ConnectAgent ca = (ConnectAgent) ios.SgetAttribute("CA_Key");

		if ( ca == null )
			ca = ios.getM_ca();

		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String spath = null;

		if (OHInterface.getG_server().getM_temppath() !=null )
			spath = OHInterface.getG_server().getM_temppath();
		else
			spath = "e:/jbm/file/cache/";

		spath += df.format(new Date()) + '/';

		if (ca != null && ca.getM_iaccount() != null )
			spath += ca.getM_iaccount().getM_account_id();

		File path = new File(spath);

		if (!path.exists())
			path.mkdirs();
		sp = spath + "/";

		if (fob.hasStorename())
			sp += fob.getStorename();
		else
		{
			String sname = UUID.randomUUID().toString() + '-' + fob.getFilename();

			fob.setStorename(sname);
			sp += sname;
		}

		fob.setFilepath(sp);

//		raf_name = sp;
		raf = new RandomAccessFile(sp,"rw");
		raf.setLength(filesize);

		return fob.build();
	}

	public boolean Decode(Object oin) throws Exception
	{
		byte[] buffer = (byte[])oin;

//		RandomAccessFile raf = new RandomAccessFile(raf_name, "rw");

		raf.write(buffer);

		if ( recvsize + buffer.length == filesize )
		{
			System.out.println("Trans Completed:"+iacross);
			raf.close();
			return true;
		}else
			recvsize+=buffer.length;

		return false;
	}

	public Object PreEncode(Object obj) throws Exception
	{
		PBIFileObject.IFileObject fo = null;

		if ( obj instanceof ByteString)
			fo = PBIFileObject.IFileObject.parseFrom((ByteString)obj);
		else
			fo = (PBIFileObject.IFileObject)obj;

		RandomAccessFile raf = new RandomAccessFile(fo.getFilepath(),"r");

		long size = raf.length();

		PBIFileObject.IFileObject.Builder fob = fo.toBuilder();

		fob.setFilesize(size);

		fo = fob.build();

		raf.close();

		return fo;
	}

	public boolean Encode(Object out, Object obj, PBIAcross.IAcross org) throws Exception
	{
		IoSessionShell ios = (IoSessionShell)out;

		PBIFileObject.IFileObject fo = null;

		if ( obj instanceof ByteString)
			fo = PBIFileObject.IFileObject.parseFrom((ByteString)obj);
		else
			fo = (PBIFileObject.IFileObject)obj;

		RandomAccessFile raf = new RandomAccessFile(fo.getFilepath(),"r");

		long size = raf.length();

		byte[] buffer = new byte[Short.MAX_VALUE];

		int readsize;

//		IoBuffer buf = IoBuffer.allocate(0x10000);

		WriteFuture wf = null;

		do
		{
			readsize = raf.read(buffer);

			if ( readsize != -1)
			{
/*
				buf.clear();
				buf.put( buffer,0,readsize);
				buf.flip();
*/
				if ( readsize != Short.MAX_VALUE )
					wf = ios.Swrite( new OHByte( org, Arrays.copyOfRange(buffer,0,readsize)));
				else
					wf = ios.Swrite( new OHByte( org, buffer));

				if ( wf != null )
					wf.await();
			}
		}while ( readsize != -1 );

		raf.close();

		return true;
	}
}
